package com.zzyl.nursing.service.impl;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneOffset;
import java.util.*;
import java.util.stream.Collectors;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zzyl.common.constant.HttpStatus;
import com.zzyl.common.core.domain.R;
import com.zzyl.common.core.page.TableDataInfo;

import com.zzyl.framework.web.service.TokenService;
import com.zzyl.nursing.domain.Reservation;
import com.zzyl.nursing.dto.ElderQueryDto;
import com.zzyl.nursing.dto.ReservationDto;
import com.zzyl.nursing.dto.UserLoginRequestDto;
import com.zzyl.nursing.mapper.ReservationMapper;
import com.zzyl.nursing.service.WechatService;
import com.zzyl.nursing.vo.LoginVo;
import com.zzyl.nursing.vo.TimeCountVo;
import com.zzyl.serve.domain.NursingProject;
import com.zzyl.serve.mapper.NursingProjectMapper;
import com.zzyl.serve.service.impl.NursingProjectServiceImpl;
import com.zzyl.utils.CurrentUserUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.zzyl.nursing.mapper.FamilyMemberMapper;
import com.zzyl.nursing.domain.FamilyMember;
import com.zzyl.nursing.service.IFamilyMemberService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

/**
 * 老人家属Service业务层处理
 *
 * @author laoYe
 * @date 2025-10-27
 */
@Service
public class FamilyMemberServiceImpl extends ServiceImpl<FamilyMemberMapper, FamilyMember> implements IFamilyMemberService {
    @Autowired
    private FamilyMemberMapper familyMemberMapper;
    @Autowired
    WechatService wechatService;
    @Autowired
    private NursingProjectServiceImpl nursingProjectService;

    @Autowired
    private TokenService tokenService;
    private static List<String> DEFAULT_NICKNAME_PREFIX = List.of(
            "生活更美好",
            "大桔大利",
            "日富一日",
            "好柿开花",
            "柿柿如意",
            "一椰暴富",
            "大柚所为",
            "杨梅吐气",
            "天生荔枝"
    );

    /**
     * 查询老人家属
     *
     * @param id 老人家属主键
     * @return 老人家属
     */
    @Override
    public FamilyMember selectFamilyMemberById(Long id) {
        return getById(id);
    }

    /**
     * 查询老人家属列表
     *
     * @param familyMember 老人家属
     * @return 老人家属
     */
    @Override
    public List<FamilyMember> selectFamilyMemberList(FamilyMember familyMember) {
        return familyMemberMapper.selectFamilyMemberList(familyMember);
    }

    /**
     * 新增老人家属
     *
     * @param familyMember 老人家属
     * @return 结果
     */
    @Override
    public int insertFamilyMember(FamilyMember familyMember) {
        return save(familyMember) ? 1 : 0;
    }

    /**
     * 修改老人家属
     *
     * @param familyMember 老人家属
     * @return 结果
     */
    @Override
    public int updateFamilyMember(FamilyMember familyMember) {
        return updateById(familyMember) ? 1 : 0;
    }

    /**
     * 批量删除老人家属
     *
     * @param ids 需要删除的老人家属主键
     * @return 结果
     */
    @Override
    public int deleteFamilyMemberByIds(Long[] ids) {
        return removeByIds(Arrays.asList(ids)) ? 1 : 0;
    }

    /**
     * 删除老人家属信息
     *
     * @param id 老人家属主键
     * @return 结果
     */
    @Override
    public int deleteFamilyMemberById(Long id) {
        return removeById(id) ? 1 : 0;
    }

    @Override
    public LoginVo login(UserLoginRequestDto dto) {
        LoginVo vo = new LoginVo();
        //1获取OpenID
        String openid = wechatService.getOpenId(dto.getCode());
        //2通过openID查询用户信息
        FamilyMember member = lambdaQuery().eq(FamilyMember::getOpenId, openid).one();
        //3获取手机号码
        String phone = wechatService.getPhone(dto.getPhoneCode());
        FamilyMember familyMember = new FamilyMember();
        familyMember.setPhone(phone);
        //4查询用户是否存在
        if (member != null) {
            //5存在
            //手机号码是否变更,有变更则更新
            vo.setNickName(member.getName());
            if (!member.getPhone().equals(phone)) {
                familyMember.setId(member.getId());
                updateById(familyMember);
            }
        } else {


            //6不存在,则新增
            familyMember.setOpenId(openid);
            //昵称
            //随机获取昵称+手机号后四位
            String nickName = generateNickName(phone);
            familyMember.setName(nickName);
            save(familyMember);
            vo.setNickName(nickName);
        }


        //7把用户ID和nickname生成token返回
        Map<String, Object> claims = new HashMap<>();
        claims.put("id", familyMember.getId());
        claims.put("nickName", vo.getNickName());
        String token = tokenService.createToken(claims);
        vo.setToken(token);
        return vo;
    }

    @Override
    public TableDataInfo<NursingProject> pageInfo(ElderQueryDto dto) {
        Page<NursingProject> page = Page.of(dto.getPageNum(), dto.getPageSize());
        //构造查询条件
        // 使用注入的服务来查询护理项目
        Page<NursingProject> pageResult = nursingProjectService.lambdaQuery()
                .eq(NursingProject::getStatus, 1)
                .page(page);
        TableDataInfo<NursingProject> result = new TableDataInfo<>(pageResult.getTotal(), pageResult.getRecords(), HttpStatus.SUCCESS, ("查询成功"));
        return result;
    }

    /**
     * 根据id查询护理项目
     *
     * @param id
     * @return
     */
    @Override
    public R<NursingProject> getId(Long id) {
        NursingProject nursingProject = nursingProjectService.getById(id);
        return R.ok(nursingProject);

    }


    /**
     * 取消预约
     */
    @Autowired
    private CurrentUserUtil currentUserUtil;
    @Autowired
    private ReservationMapper reservationMapper;

    @Override
    public Integer cancelledCount() {
        Long userId = currentUserUtil.getCurrentUserId();
        if (userId == null) {
            return 0;
        }
        LocalDateTime now = LocalDateTime.now();
        //
        LocalDateTime startOfDay = now.withHour(0).withMinute(0).withSecond(0).withNano(0);
        LocalDateTime endOfDay = now.withHour(23).withMinute(59).withSecond(59).withNano(999999999);

        Integer count = reservationMapper.selectCount(new QueryWrapper<Reservation>()
                .eq("user_id", userId)
                .eq("status", "CANCELLED")
                .ge("create_time", startOfDay)
                .lt("create_time", endOfDay)).intValue();

        return count;
    }
    /**
     * 统计时间段内预约数
     */

    @Override
    public List<TimeCountVo> countByTime(Long time) {
        LocalDate dateTime = LocalDateTime.ofEpochSecond(time / 1000L, 0, ZoneOffset.of("+8")).toLocalDate();
        List<TimeCountVo> result = new ArrayList<>();

        for (int hour = 8; hour <= 20; hour += 2) {
            LocalDateTime start = LocalDateTime.of(dateTime, LocalTime.of(hour, 0, 0));
            LocalDateTime end = start.plusHours(2);

            //查询该时间内与确定预约数
            QueryWrapper<Reservation> queryWrapper = new QueryWrapper<>();
            queryWrapper.between("time", start, end)
                    .ne("status", 2);
            Integer bookedCount = reservationMapper.selectCount(queryWrapper).intValue();
            bookedCount = bookedCount == null ? 0 : bookedCount;

            // 4. 计算剩余次数（假设每个时段最多可预约6次）
            TimeCountVo vo = new TimeCountVo();
            vo.setTime(start.toString());
            vo.setCount(6 - bookedCount);
            result.add(vo);
        }
        return result;
    }
    /**
     * 添加预约
     */

    @Override
    public void addReservation(ReservationDto dto) {
        // 1. 验证参数
        if (dto.getMobile() == null || dto.getName() == null || dto.getTime() == null || dto.getType() == null || dto.getVisitor() == null) {
            throw new IllegalArgumentException("参数不能为空");
        }
        // 2. 将时间字符串转换为 LocalDateTime
        String timeStr = dto.getTime();
        if (timeStr.contains(" ")) {
            timeStr = timeStr.replace(" ", "T"); // 替换空格为 T
        }
        LocalDateTime time = LocalDateTime.parse(timeStr);

        //3.查询该时间段是否已满
        Long bookeCount = reservationMapper.selectCount(new QueryWrapper<Reservation>()
                .eq("time", time)
                .ne("status", 2));

        if (bookeCount >= 6) {
            throw new RuntimeException("该时间段已满");
        }
        //4.创建预约记录
        Reservation reservation = new Reservation();
        reservation.setName(dto.getName());
        reservation.setMobile(dto.getMobile());
        reservation.setTime(time);
        reservation.setVisitor(dto.getVisitor());
        reservation.setType(dto.getType());


        reservation.setStatus(1); //状态默认为待处理
        reservationMapper.insert( reservation);

    }
    /**
     * 分页查询预约记录
     */

    @Override
    public TableDataInfo<ReservationDto> pageReservation(ElderQueryDto dto) {
        // 1. 构建分页对象
        Page<Reservation> page = new Page<>(dto.getPageNum(), dto.getPageSize());

        // 2. 构建查询条件
        QueryWrapper<Reservation> queryWrapper = new QueryWrapper<>();
        if (dto.getStatus() != null) {
            queryWrapper.eq("status", dto.getStatus());
        }


        // 3. 执行分页查询
        Page<Reservation> reservationPage = reservationMapper.selectPage(page, queryWrapper);

        // 4. 转换为DTO并封装结果
        TableDataInfo<ReservationDto> result = new TableDataInfo<>();
        result.setTotal(reservationPage.getTotal());
        result.setRows(reservationPage.getRecords().stream()
                .map(this::convertToDto) // 转换为ReservationDto
                . collect(Collectors.toList()));
        return result;


    }
    /**
     * 取消预约
     */

    @Override
    public void cancelReservation(Long id) {
        UpdateWrapper<Reservation> updateWrapper=new UpdateWrapper<>();
        updateWrapper.eq("id",id);
        // 2. 设置更新内容：将状态改为“已取消”（假设status=2代表已取消，需与业务定义对齐）
        // 同时记录取消时间（若表中有cancel_time字段
        Reservation updateEntity = new Reservation();
        updateEntity.setStatus(2);
        // 执行更新操作
        reservationMapper.update(updateEntity, updateWrapper);
    }

    private ReservationDto convertToDto(Reservation reservation) {
        ReservationDto dto = new ReservationDto();
        dto.setMobile(reservation.getMobile());
        dto.setName(reservation.getName());
        dto.setTime(reservation.getTime().toString());
        dto.setVisitor(reservation.getVisitor());
        dto.setType(reservation.getType());
        return dto;

    }


    /**
     * 随机生成昵称
     *
     * @param phone
     * @return
     */
    private String generateNickName(String phone) {
        Random r = new Random();
        int prefixIndex = r.nextInt(DEFAULT_NICKNAME_PREFIX.size());
        String preficx = DEFAULT_NICKNAME_PREFIX.get(prefixIndex);
        //获取手机后四位
        String suffix = phone.substring(phone.length() - 4);
        return preficx + suffix;

    }
}
